package com.curluin.model;

import java.util.Vector;

import com.curluin.approximateShapes.ApproximateShape;
import com.curluin.math.MyVector;
import com.curluin.scene.Node;
import com.curluin.scene.TriangleMesh;
/**
 * @author Alex, Jo
 *
 */
public abstract class ModelObject {

	public static final String LOG_TAG="ModelObject";
	
	//TODO move constants to physics class
	public static final int CONSITENCY_HARD_AS_ICE = 0;
	public static final int CONSITENCY_SOFT = 1;
	public static final int CONSITENCY_FLUID = 2;
	
	
	/**
	 * Vector representing the position
	 */
	public MyVector position;
	
	/**
	 * Approximated shape of the Object 
	 */
	public ApproximateShape shape;
	
	/**
	 * Node for visualisation purposes, contains 3D structure of Object (TriangleMeshes)
	 */
	public Node node;

	
	protected int consistency;
	/**
	 * Color used for Debugging
	 */
	 MyVector debugColor;

	/**
	 * Constructor. Assure to call 'initialize()' at the end of the constructor of every object which inherits from ModelObject
	 * @param consitency 
	 * @param position: every ModelObject has a initial position in the level
	 */
	public ModelObject(MyVector position, int consistency){
		this.position = position;
		this.node = new Node(position);
		this.consistency=consistency;
		// Call 'if(this.getClass().equals(<specific class>.class)) initialize();' here in every inherited constructor
	}
	
	public ModelObject(TriangleMesh mesh, MyVector position,  int consistency){
		this.position = position;
		this.node = new Node(position);
		node.addChild(mesh);
		this.consistency=consistency;
		// Call 'if(this.getClass().equals(<specific class>.class)) initialize();' here in every inherited constructor
	}
	
	protected void initialize(MyVector position, int positionMode){
		if(node.getChildren().isEmpty()){
			node.addChild(composeGraphics());
		}
		node.updateOutersizeAndCenter();
//		Log.e(LOG_TAG, "pos "+node.getCenter()+" size "+getSize()+" center "+node.center);
		node.setPosition(position, Node.RESET, positionMode);
//		Log.e(LOG_TAG, "pos "+node.getCenter()+" size "+getSize());
		this.position = node.getCenter();
		shape = initializeApproximateShape();
		
//		initializeApproximateShape();
	}

	/**
	 * Getter for node
	 */
	public Node getNode(){
		return node;
	}

	public MyVector getDebugColor(){
		return debugColor;
	}
	/**
	 * Scans the approximate shape of this ModelObject with the given sample rate.
	 * Further information see: {@link com.curluin.approximateShapes.ApproximateShape#initializeScanData(float)}
	 * @param sampleRate
	 * @return
	 */
	public Vector<MyVector> scanApproximateShape(float sampleRate) {
		return shape.scan(sampleRate,false);
//		return node.scan(sampleRate);
	}

	/**
	 * returns the initial graphical node, automatically called by Constructor of ModelObject  
	 * @return initial node
	 */
	protected abstract Node composeGraphics();

	/**
	 * returns the initial ApproximateShape, automatically called by Constructor of ModelObject to set shape (see {@link com.curluin.model.ModelObject.shape})
	 * @return initial AprroximateShape
	 */
	protected abstract ApproximateShape initializeApproximateShape();
//	protected void initializeApproximateShape(){
//		node.initializeShape();
//	}

	@Override
	public boolean equals(Object o){
		if(! (o instanceof ModelObject)) return false;
		ModelObject mo=(ModelObject) o;
		return this.position.equals(mo.position);
	}

	/**
	 * Sets position of ModelObject and adjusts that of its children
	 * @param position
	 * @param additionally
	 */
	public void setPos(MyVector position, boolean additionally){
		this.position = additionally ? this.position.add(position) : position;
		node.setPosition(position, additionally, Node.CENTER);
	}	

	/**
	 * Copy of outer size of node. This equals the maximal bounds of the Object
	 * @return
	 */
	public MyVector getSize(){
		return MyVector.makeCopy(node.outerSize);
	}

	/**
	 * Copy of center of the Object in openGl-Coordinates
	 * @return
	 */
	public MyVector getCenter(){
		return node.getCenter();
	}
	
	public int getConsitency(){
		return consistency;
	}

	
}
